//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    public abstract class DataSource : IOfficeXmlSerializable, INotifyPropertyChanged
    {
        private ExtensionElement _extension;
        public abstract IEnumerable<object> Values { get; }

        public ExtensionElement Extension
        {
            get { return _extension; }
            set { _extension = value; }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            ReadXmlCore(context);
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            WriteXmlCore(context);
        }

        #endregion

        protected abstract void ReadXmlCore(ReadContext context);

        protected abstract void WriteXmlCore(WriteContext context);


        protected void NotifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }


        internal static DataSource ReadOptionalDataSource(string name, ReadContext context)
        {
            if (context.ReaderLocalName != name)
                return null;
            using (var c = context.Read(name))
            {
                switch (c.ReaderLocalName)
                {
                    case "strRef":
                        return StringReference.ReadStringReference(c);
                    case "numRef":
                        return NumericReference.ReadNumericReference(c);
                    case "multiLvlStrRef":
                        return MultiLevelStringReference.ReadMultiLevelStringReference(c);
                    case "strLit":
                        StringData data = new StringData();
                        IOfficeXmlSerializableAs a = data;
                        a.ReadXmlAs ("strLit", c);
                        return data;
                    case "numLit":
                        NumericLiteral numLit = new NumericLiteral();
                        numLit.ReadXmlCore(c);
                        return numLit;
                    default:
                        throw new NotSupportedException();
                }
            }
        }
    }
}